import { initWebGPU } from '../_shared'
import fragmentCode from '@shaders/traingle/demo1/traingle.frag.wgsl?raw'
import vertexCode from '@shaders/traingle/demo1/traingle.vert.wgsl?raw'

await main()

async function main() {
  const { adapter, device, format, context } =
    await initWebGPU(document.querySelector('canvas') as HTMLCanvasElement)
  const { pipeline } = await initGPUPipeline({
    device,
    format,
    vertexCode,
    fragmentCode,
  })
  await draw({
    device,
    context,
    pipeline,
  })
}

interface InitGPUPipelineProps {
  device: GPUDevice;
  format: GPUTextureFormat;
  vertexCode: string;
  fragmentCode: string;
}

async function initGPUPipeline({ device, format, vertexCode, fragmentCode }: InitGPUPipelineProps) {
  const layout = device.createPipelineLayout({
    bindGroupLayouts: [],
  })
  const vertexShaderModule = device.createShaderModule({
    code: vertexCode,
  })
  const fragmentShaderModule = device.createShaderModule({
    code: fragmentCode,
  })
  const pipeline = await device.createRenderPipelineAsync({
    layout,
    vertex: {
      module: vertexShaderModule,
      entryPoint: 'main',
    },
    fragment: {
      module: fragmentShaderModule,
      entryPoint: 'main',
      targets: [
        {
          format,
        },
      ],
    },
    primitive: {
      topology: 'triangle-list',
    },
  })
  return { pipeline, layout }
}

interface DrawProps {
  device: GPUDevice;
  context: GPUCanvasContext;
  pipeline: GPURenderPipeline;
}

async function draw({ device, context, pipeline }: DrawProps) {
  const encoder = device.createCommandEncoder()
  const renderPass = encoder.beginRenderPass({
    colorAttachments: [
      {
        view: context.getCurrentTexture().createView(),
        loadOp: 'clear',
        clearValue: { r: 0, g: 0, b: 0, a: 1 },
        storeOp: 'store',
      },
    ],
  })
  renderPass.setPipeline(pipeline)
  renderPass.draw(3)
  renderPass.end()
  const buffer = encoder.finish()
  device.queue.submit([buffer])
}